昨天我們討論 MVVM 架構,並介紹如何使用 @Published
和 @StateObject
在 SwiftUI 中實現資料與 View 的同步。在練習過程中,我們使用到一個叫做 List 的元件來顯示清單,但還沒有詳細介紹 List 的用途和特性。今天,我們將進一步實作 List,將它整合到主畫面中,用來顯示我們的家用品清單。
List
是 SwiftUI 中一個非常常用的元件,有點像 UIKit 中的 UITableView,它被用來顯示一組資料的垂直列表。無論是顯示簡單的文字清單,還是建立複雜的自定義佈局,List
都能輕鬆應對。它內建了滾動和資料更新等功能,非常適合用來展示需要動態更新的資料清單。
List
也支援刪除、複選、多維資料顯示等功能,但由於我們尚未實作資料的異動,這部分會等待至之後再介紹。如果對這些進階功能有興趣,可以參考下方的資料來進一步了解!
我們將繼續使用昨天定義的 ItemViewModel,並在主畫面中使用 List
來顯示家用品的名稱和數量。我們回顧一下 ItemViewModel 的結構:
class ItemViewModel: ObservableObject {
@Published var items: [Item] = [
Item(name: "牛奶", quantity: 2),
Item(name: "麵包", quantity: 1)
]
func addItem(name: String, quantity: Int) {
let newItem = Item(name: name, quantity: quantity)
items.append(newItem)
}
}
接下來,我們在主畫面中使用 List
來顯示這些資料:
struct ContentView: View {
@StateObject var viewModel = ItemViewModel()
var body: some View {
List(viewModel.items) { item in
HStack {
Text(item.name)
.font(.headline)
Spacer()
Text("數量: \(item.quantity)")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding(.vertical, 8)
}
}
}
List
來遍歷 viewModel.items,並將每個 Item 顯示為列表中的一行。List
會自動處理資料的佈局,並且當 items 發生變化時,自動更新列表顯示。HStack
來橫向排列物品的名稱和數量。這樣可以讓列表項目更加整齊有序。Spacer
用來在名稱和數量之間增加空間,讓它們對齊兩側。Text
來顯示物品名稱和數量,並使用不同的字型和顏色來區分它們。List
不僅能夠自動處理資料的顯示與佈局,還能夠在資料變動時自動更新,我們在 ItemViewModel 中使用了 @Published
屬性,這樣一來,當資料發生變化時,List
會立即顯示最新的內容,而不需要我們手動更新 UI。
除了 List,SwiftUI 還提供了其他元件來顯示列表或集合資料。這些元件各有不同的用途和優勢,可以根據不同的需求靈活選擇。
ForEach
通常與 VStack
、HStack
或 ZStack
等元件結合使用,適合用來顯示靜態的佈局或不需要滾動的簡單列表。這種元件適合用在顯示少量固定的項目,或者在自訂 UI 佈局中嵌入多個子元件時使用。VStack {
ForEach(0..<5) { index in
Text("項目 \(index)")
}
}
參考資料:
.horizontal
或 .vertical
控制捲動的方向),常與 ForEach
結合使用。ScrollView
可以讓使用者滾動瀏覽內容。這個元件非常適合用來顯示長列表、圖片庫或其他需要滾動的資料。通常與 ForEach
或 LazyVStack
等元件結合使用。ScrollView {
VStack {
ForEach(0..<50) { index in
Text("項目 \(index)")
}
}
}
參考資料:
LazyVStack
和 LazyHStack
和 VStack
和 HStack
類似,但卻不同。不同於它們僅在需要時才載入內容,這對於顯示大量資料時能夠顯著提高效能。ScrollView {
LazyVStack {
ForEach(0..<100) { index in
Text("項目 \(index)")
}
}
}
ScrollView(.horizontal) {
LazyHStack(spacing: 16) {
ForEach(0..<100) { index in
Text("項目 \(index)")
.padding(.horizontal, 16)
.padding(.vertical, 8)
.background(Color.blue.opacity(0.7))
.foregroundColor(.white)
.cornerRadius(8)
}
}
.padding()
}
參考資料:
LazyVGrid
和 LazyHGrid
是用來顯示格狀佈局資料的元件,與 LazyVStack
和 LazyHStack
類似,會在使用時才載入內容。這些元件在大量資料顯示時具有更好的效能表現。LazyVGrid
和 LazyHGrid
。它們能夠靈活處理格子的大小和佈局,適合展示需要多列或多行顯示的內容。let columns = [
GridItem(.flexible()),
GridItem(.flexible())
]
ScrollView {
LazyVGrid(columns: columns) {
ForEach(0..<50) { index in
Text("項目 \(index)")
}
}
}
let columns = [
GridItem(.fixed(50)),
GridItem(.fixed(50))
]
ScrollView(.horizontal) {
LazyHGrid(rows: columns, spacing: 16) {
ForEach(0..<50) { index in
Text("項目 \(index)")
}
}
}
參考資料:
Table
是專門用於 macOS 的元件,用來顯示表格式資料。struct Person: Identifiable {
let givenName: String
let familyName: String
let emailAddress: String
let id = UUID()
var fullName: String { givenName + " " + familyName }
}
@State private var people = [
Person(givenName: "Juan", familyName: "Chavez", emailAddress:
"juanchavez@icloud.com"),
Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com"),
Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com"),
Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com")
]
struct PeopleTable: View {
var body: some View {
Table(people) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
TableColumn("E-Mail Address", value: \.emailAddress)
}
}
}
今天我們認識 SwiftUI 中顯示列表的各種元件,尤其是 List
元件,並學習了如何使用它來顯示家用品清單。我們還簡單介紹其他幾個常用的列表元件,如 ForEach
、ScrollView
、LazyVStack
和 LazyVGrid
,這些元件能夠幫助我們更靈活地處理不同類型的資料顯示需求。透過這些元件,我們能夠輕鬆創造出高效、美觀的 UI。
明天,我們將進一步學習如何在列表中新增與刪除項目,敬請期待!